import logging
import os
import os.path
import shutil
import subprocess
import sys

from pylons import request, response, session, tmpl_context as c
from pylons.controllers.util import abort, redirect_to
from pylons import config
from authkit.authorize.pylons_adaptors import authorize
from authkit.permissions import RemoteUser, ValidAuthKitUser, UserIn

from arkaiv.lib.base import BaseController, render, model
from arkaiv.model.cmmlparser import cmmlParser
from arkaiv.model.oggzinfo import OggzInfo
from arkaiv.model.framer import Frame
from arkaiv.model.imager import Imager

log = logging.getLogger(__name__)

archive_loc = config['archive_loc']

class AddmediaController(BaseController):

    @authorize(ValidAuthKitUser())
    def __before__(self):
        pass

    def index(self):
        # Return a rendered template
        #return render('/addmedia.mako')
        # or, return a response
        collectionlist = model.getcollections()
        c.collectioninfo = ""
        for collection in collectionlist:
            c.collectioninfo = c.collectioninfo + "<option>" + collection['name'] + "</option>"

        return render('/addannodexform.mak')

    def addannodexmedia(self):
        cmmlsource = request.POST['cmmlfile']
        oggsource = request.POST['oggfile']

	# If there is no ogg file, then return an error
	if (oggsource == ""):
	    return render ('/nosourcefileerror.mak')

        if (self.__addmediatoarchive(cmmlsource, oggsource) == "file exists"):
            return render ('/fileexistsmessage.mak')
        else:
            redirect_to(controller='list', action='index')

    def __addmediatoarchive(self, cmmlsource, oggsource):
        # Deal with the cmml file
        # if no cmml file has been entered, then create one
        if cmmlsource=="":
            print "creating source file"
            basecmmlname = os.path.splitext(oggsource.filename)[0].replace(' ',"") + ".cmml"
            newcmmlname = os.path.join(archive_loc, basecmmlname)
            parser = cmmlParser()
            #parser.setcmmlfilename(newcmmlname)
            fulloggpath = os.path.join(archive_loc, oggsource.filename)
            if os.path.isfile(newcmmlname):
                print "File exists - bail time"
                return "file exists" 
            parser.createnewfile(newcmmlname, fulloggpath)

        else:
            newcmmlname = os.path.join(archive_loc, cmmlsource.filename.replace(' ',""))
            permanent_file = open(newcmmlname, 'w')
            shutil.copyfileobj(cmmlsource.file, permanent_file)
            cmmlsource.file.close()
            permanent_file.close()
           
            # Now the ogg file...
        # FIXME whitespace is dealt with in a very clumsy manner
        newoggname = os.path.join(archive_loc, oggsource.filename.replace(' ', ""))
        permanent_file = open(newoggname, 'w')
        shutil.copyfileobj(oggsource.file, permanent_file)
        oggsource.file.close()
        permanent_file.close()

        basename = os.path.splitext(newoggname)[0]
        imagedirname = basename + "_clipimages"
        # Create a directory for clip images
        if not os.path.isdir(imagedirname):
            os.makedirs(imagedirname, mode=0755)

        # Get the title for the item (head title)
        parser = cmmlParser()
        parser.setcmmlfilename(newcmmlname)
        title = parser.gettitle() 
        # adding an item here, even though we don't actually have the source
        # anx file in place yet...
        newanxname = basename + ".anx"
        newitemid = model.addsource(title, newoggname, newcmmlname)

        # Need to update the source tag in the cmml file 
        parser.updatesourcetag(newoggname)
        parser.addmetaid(newitemid) 

        headinfo = {}
        headinfo['itemid']= newitemid 
        headinfo['id'] = ""
        headinfo['title'] = title
        headid = model.addhead(headinfo)

        # Now extract any clip information and add it to the database
	    # get a list of dictionary objects

        o = OggzInfo(newoggname)
        cliplist = parser.getclipsfromcmml()  
        for clipdict in cliplist:
            clipdict['itemid'] = newitemid
            if o.has_video():
                # get a still image for the correct frame
                print "getting a clip image"
                try:
                    # this fails very badly - stopping the web server even, so 
                    # has been disabled for the moment.
                    print "multiple clip image import disabled for now"
                    clipimage = Imager()
                    clipdict['img_src'] = clipimage.createimageforclip(newcmmlname, clipdict)
                except:
                    print "problem with clip image for id " + str(clipdict['itemid'])
                    clipdict['img_src'] = ""
            else:
                clipdict['img_src'] = ""
            model.addclip(clipdict)

        # Check whether the ogg file has any existing vorbis comments/tags
        # and import them as meta tags

        parser = cmmlParser()
        parser.setcmmlfilename(newcmmlname)
        metalist = parser.getheadinfofromcmml()

        cmd = "vorbiscomment -l " + newoggname
        runit = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE , stderr=subprocess.PIPE)
        out, err = runit.communicate()

        for line in out.splitlines():
            metadict={}
            print line
            tag = line.split("=")
            metadict['name'] = tag[0]
            metadict['content'] = tag[1]
            metadict['id'] = tag[0]
            metadict['scheme'] = ""
            metalist.append(metadict)
            
        # Extract meta info from the head and add to database

        for metadict in metalist:
            metadict['headindex'] = headid
            metadict['itemid'] = newitemid
            model.addmeta(metadict)

        # Now we read the meta tags back from the database, and write them into
        # the cmml file, syncing the id tags - useful (essential) for editing
        # these later.
        metalist = model.getmetasforhead(headid)
        # sync cmml id attribute of head metas with the database primary key
        for meta in metalist:
            model.syncmetaid(meta.ixm)

        # and sync with the cmml file
        # Probably best to do it in one go at this stage
        parser.setcmmlfilename(newcmmlname)
        parser.syncheadmetas(metalist) 

        collection = request.params['collection'] 
        model.additemtocollection(headinfo['itemid'], collection)
 
        return

    def __localdirimport(self, cmmlfilename, oggfilename): 
        print os.path.split(cmmlfilename)
#        if os.path.split(cmmlfilename)[1] == "":
        if (not os.path.isfile(cmmlfilename)):
            # create new cmmlfile
            baseoggname = os.path.split(oggfilename)[1]
            basecmmlname = os.path.splitext(baseoggname)[0].replace(' ',"") + ".cmml"
            print "basecmmlname: " + basecmmlname
            print "archive_loc: " + archive_loc
            newcmmlname = os.path.join(archive_loc, basecmmlname)
            print "newcmmlname: " + newcmmlname
            parser = cmmlParser()
            fulloggpath = os.path.join(archive_loc, baseoggname)
            if os.path.isfile(newcmmlname):
                print "File exists - bail time"
                return "file exists" 
            parser.createnewfile(newcmmlname, fulloggpath)

        else:
            newcmmlname = os.path.join(archive_loc, os.path.split(cmmlfilename)[1])
            permanent_file = open(newcmmlname, 'w')
            sourcefile = open(cmmlfilename, 'r')
            shutil.copyfileobj(sourcefile, permanent_file)
            sourcefile.close()
            permanent_file.close()
       
        # Now the ogg file...
        baseoggname = os.path.split(oggfilename)[1]
        baseoggname = baseoggname.replace(' ',"")
        newoggname = os.path.join(archive_loc, baseoggname)
#        newoggname = os.path.join(archive_loc, os.path.split(oggfilename)[1])
        permanent_file = open(newoggname, 'w')
        sourcefile = open(oggfilename, 'r')
        shutil.copyfileobj(sourcefile, permanent_file)
        sourcefile.close()
        permanent_file.close()

        # shouldn't the image directory stuff happen here?
        basename = os.path.splitext(newoggname)[0]
        imagedirname = basename + "_clipimages"
        # Create a directory for clip images
#        print imagedirname
        if not os.path.isdir(imagedirname):
            os.makedirs(imagedirname, mode=0755)
 
        # Get the title for the item (head title)
        parser = cmmlParser()
        parser.setcmmlfilename(newcmmlname)
        title = parser.gettitle() 
        # adding an item here, even though we don't actually have the source
        # anx file in place yet...
        basename = os.path.splitext(newoggname)[0]
        newanxname = basename + ".anx"
 
        newitemid = model.addsource(title, newoggname, newcmmlname)
       # Need to update the source tag in the cmml file 
        parser.updatesourcetag(newoggname)
        parser.addmetaid(newitemid) 
 
        headinfo = {}
        headinfo['itemid']= newitemid 
        headinfo['id'] = ""
        headinfo['title'] = title
        headid = model.addhead(headinfo)
        # Now extract any clip information and add it to the database
        # get a list of dictionary objects
        cliplist = parser.getclipsfromcmml()  
        for clipdict in cliplist:
            clipdict['itemid'] = newitemid
            model.addclip(clipdict)

        # Check whether the ogg file has any existing vorbis comments/tags
        # and import them as meta tags

        parser = cmmlParser()
        parser.setcmmlfilename(newcmmlname)
        metalist = parser.getheadinfofromcmml()

        cmd = "vorbiscomment -l " + newoggname
        print "cmd: " + cmd
        runit = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE , stderr=subprocess.PIPE)
        out, err = runit.communicate()

        for line in out.splitlines():
            metadict={}
            print line
            tag = line.split("=")
            metadict['name'] = tag[0]
            metadict['content'] = tag[1]
            metadict['id'] = tag[0]
            metadict['scheme'] = ""
            metalist.append(metadict)
  
        # Extract meta info from the head and add to database
        for metadict in metalist:
            metadict['headindex'] = headid
            metadict['itemid'] = newitemid
            model.addmeta(metadict)

        # Now we read the meta tags back from the database, and write them into
        # the cmml file, syncing the id tags - useful (essential) for editing
        # these later.
        metalist = model.getmetasforhead(headid)
        # sync cmml id attribute of head metas with the database primary key
        for meta in metalist:
            model.syncmetaid(meta.ixm)

        # and sync with the cmml file
        # Probably best to do it in one go at this stage
        parser.setcmmlfilename(newcmmlname)
        parser.syncheadmetas(metalist) 

        collection = request.params['collection'] 
        model.additemtocollection(headinfo['itemid'], collection)
        return		

    def addannodexindirform(self):
        # Currently unused - useful if importing a load of material locally
        collectionlist = model.getcollections()
        c.collectioninfo = ""
        for collection in collectionlist:
            #print collection.name
            c.collectioninfo = c.collectioninfo + "<option>" + collection['name'] + "</option>"

        return render('/addannodexindirform.mak')

    def addannodexindirmedia(self):
        directory = request.params['mediadir']
        files = os.listdir(directory)
        for file in files:
            try:
                if os.path.splitext(file)[1] == ".ogg":
                    cmmlfilename = directory + os.path.splitext(file)[0] + ".cmml"
                    oggfilename = directory + file
                    print "importing: " + cmmlfilename + " " + oggfilename
                    self.__localdirimport(cmmlfilename, oggfilename)
                else:
                    print "moving right past: " + file
            except:
                print " problem with " + file
        return
 
